package com.xiaolin.renju.service;

import com.xiaolin.renju.kernel.RenJuKernel;
import com.xiaolin.renju.pojo.HttpData;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;

import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author zhengjin.liu
 * @since 2021/12/2 16:34
 */
@Service
public class RenJuService {

    private final String notKernelMessage = "当前棋局已销毁！请重新开局！";

    private List<RenJuKernel> kernels = new ArrayList<>();

    @Scheduled(cron = "0 0/5 * * * ?")
    public void runJob() {
        // 销毁过时的核心
        try {
            kernels.stream().filter(RenJuKernel::isOvertime).forEach(RenJuKernel::destroy);
        } catch (Exception e) {
            e.printStackTrace();
        }
        kernels = kernels.stream().filter(k -> !k.isOvertime()).collect(Collectors.toList());
    }

    @PreDestroy
    public void destroy() {
        for (RenJuKernel kernel : kernels) {
            kernel.destroy();
        }
    }

    public HttpData start(HttpData data) {
        try {
            RenJuKernel kernel = getRenJuKernel(data.getId());
            if (Objects.isNull(kernel)) {
                kernel = new RenJuKernel();
            }
            if (data.getTimeoutTurn() != null
                    && data.getTimeoutTurn() > 50
                    && data.getTimeoutTurn() < 100000) {
                kernel.setTimeoutTurn(data.getTimeoutTurn());
            }
            kernels.add(kernel);
            data.setCode("ok");
            data.setId(kernel.start());
        } catch (Exception e) {
            e.printStackTrace();
            data.setCode("error");
            data.setMessage(e.getMessage());
        }
        return data;
    }

    public HttpData turn(HttpData data) {
        if (data.getId() == null) {
            data.setMessage("id不能为空！");
            data.setCode("error");
            return data;
        }
        final RenJuKernel kernel = getRenJuKernel(data.getId());
        if (Objects.isNull(kernel)) {
            data.setMessage(notKernelMessage);
            data.setCode("error");
            return data;
        }
        final String turn = kernel.turn(data.getY(), data.getX());
        setPlace(data, turn);
        return data;
    }

    private void setPlace(HttpData data, String turn) {
        final String[] split = turn.split(",");
        data.setY(Integer.parseInt(split[0]));
        data.setX(Integer.parseInt(split[1]));
        data.setCode("ok");
    }

    private RenJuKernel getRenJuKernel(String id) {
        if (id == null) {
            return null;
        }
        return kernels.stream()
                .filter(k -> id.equals(k.getId()))
                .findFirst()
                .orElse(null);
    }

    public HttpData beat(HttpData data) {
        final RenJuKernel kernel = getRenJuKernel(data.getId());
        if (kernel == null) {
            data.setMessage(notKernelMessage);
            data.setCode("error");
        } else {
            kernel.beat();
            data.setCode("ok");
        }
        return data;
    }

    public HttpData begin(HttpData data) {
        final RenJuKernel kernel = getRenJuKernel(data.getId());
        if (kernel == null) {
            data.setMessage(notKernelMessage);
            data.setCode("error");
        } else {
            final String begin = kernel.begin();
            setPlace(data, begin);
        }
        return data;
    }

    public HttpData takeBack(HttpData data) {
        final RenJuKernel kernel = getRenJuKernel(data.getId());
        if (kernel == null) {
            data.setMessage(notKernelMessage);
            data.setCode("error");
            return data;
        }
        if (kernel.takeBack()) {
            data.setCode("ok");
        } else {
            data.setMessage("当前不能悔棋！！");
            data.setCode("error");
        }
        return data;
    }
}
